/**
 * Colony.java
 *
 * Roslan's Remake of MOO in 3D using Ardor3D
 * (C) 2010-2012 Roslan Amir. All rights reserved.
 */

package name.roslan.games.moo3d.data;

import name.roslan.games.moo3d.GameBase;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class represents the player's or AI's colony. It contains all the attributes for a colonized star.
 * 
 * @author Roslan Amir
 * @version 1.0 - Jan 8, 2011
 */
public class Colony extends Star {

    /**
     * 
     */
    private static final Logger logger = LoggerFactory.getLogger(GameBase.class);

    /**
     * Starting population of each home world. For Easy and Normal difficulty, this is 50. For Hard, this is 40.
     */
    private static final int[] HOMEWORLD_INITIAL_POPULATION = { 50, 50, 40 };

    /**
     * Starting factory count of each home world.
     */
    private static final int HOMEWORLD_INITIAL_FACTORIES = 30;

    /**
     * Starting population of each new colony.
     */
    private static final int COLONY_INITIAL_POPULATION = 2;

    /**
     * How much production (in BC) a factory produces.
     */
    private static final int PRODUCTION_PER_FACTORY = 1;

    /**
     * Names of each planetary shield level: 0=None, 1=Class V, 2=Class X, 3=Class XV, 4=Class XX.
     */
    private static final String[] PLANETARY_SHIELD_CLASS = { "", "V", "X", "XV", "XX" };

    /**
     * Costs of each planetary shield level: 0=None, 1=Class V, 2=Class X, 3=Class XV, 4=Class XX.
     */
    private static final int[] PLANETARY_SHIELD_COST = { 0, 3000, 6000, 12000, 24000 };

    /**
     * The current population of this colony.
     */
    public int population;

    /**
     * The number of factories (fully completed) currently available on this colony.
     */
    public int factories;

    /**
     * The current capacity (maximum possible population) of this colony, for example, after terraforming. Initially the same as the planet size.
     */
    public int capacity;

    /**
     * The maximum number of factories that can be currently built on this colony.
     */
    public int maxBuildableFactories;

    /**
     * The percentage of partially completed factory on this colony (between 0 and 1 exclusive).
     */
    public float partialFactories;

    /**
     * The number of missile bases operational.
     */
    public int bases;

    /**
     * Total ship maintenance cost.
     */
    public int totalShipMaintenance;

    /**
     * The base production produced by this colony.
     */
    public int baseProduction;

    /**
     * The net production produced by this colony.
     */
    public int netProduction;

    /**
     * The accumulated waste generated by this colony's factories.
     */
    public float waste;

    /**
     * Constructor - constructs a new <code>Colony</code> with the given indices.
     * 
     * @param starIndex - the index into the <code>STAR_NAMES</code> array for this star.
     * @param colorIndex - the index into the <code>STAR_DESCRIPTION</code> array for this star.
     */
    public Colony(int starIndex, int colorIndex) {
        super(starIndex, colorIndex);
    }

    /**
     * Create the home world for the specified player or non-player race.
     * 
     * @param race - the race who owns this home world
     * @param difficultyIndex - the difficulty index for this game (determines the initial population)
     * @return the <code>Colony</code> object representing the home world of the specified race
     */
    public static Colony createHomeWorld(Race race, int difficultyIndex) {
        /*
         * Create and initialize the colony's star's attributes.
         */
        Colony colony = new Colony(race.raceIndex, 0); // the home worlds are at index 0-9, color is yellow for all home stars
        colony.planetSize = Star.HOMEWORLD_PLANET_SIZE;
        colony.environment = Environment.TERRAN;
        colony.fertility = Fertility.NORMAL;
        colony.minerals = Minerals.NORMAL;
        colony.research = Research.NORMAL;
        colony.bcPerProduction = Star.BC_PER_PRODUCTION_NORMAL;
        colony.growthRate = Star.GROWTH_RATE_NORMAL;
        colony.rpPerProduction = Star.RP_PER_PRODUCTION_NORMAL;
        colony.specials = colony.makeSpecials();
        colony.owner = race;
        colony.explored = true;

        /*
         * Initialize the new colony standard attributes.
         */
        colony.population = Colony.HOMEWORLD_INITIAL_POPULATION[difficultyIndex];
        colony.factories = Colony.HOMEWORLD_INITIAL_FACTORIES;
        colony.initColonyStandardAttributes();

        return colony;
    }

    /**
     * Initialize the new colony standard attributes.
     */
    private void initColonyStandardAttributes() {
        /*
         * Initialize the colony's attributes.
         */
        this.capacity = this.planetSize;
        this.maxBuildableFactories = this.capacity * this.owner.factoriesPerPopulation; // maximum factories that can be built
        this.partialFactories = 0.0f;
        this.bases = 0;
        this.totalShipMaintenance = 12; // temporary

        /*
         * Calculate the productions and waste.
         */
        this.updateBaseProduction();
        this.updateNetProduction();
        this.waste = 0.0f;
    }

    /**
     * Calculate and return the base production for this colony.
     */
    private void updateBaseProduction() {
        int usableFactories = this.population * this.owner.factoriesPerPopulation;
        if (usableFactories > this.factories)
            usableFactories = this.factories;
        int productionFromFactories = usableFactories * Colony.PRODUCTION_PER_FACTORY;
        float productionFromPopulation = this.population * this.owner.productionPerPopulation;
        this.baseProduction = (int) (productionFromFactories + productionFromPopulation);
    }

    /**
     * Calculate and return the net production for this colony.
     */
    private void updateNetProduction() {
        this.netProduction = this.baseProduction - this.totalShipMaintenance;
    }

}
